// https://www.luogu.com.cn/problem/P1005
#include <algorithm>
#include <cstdio>
#include <cstring>
using namespace std;
using T = int;
T rad();  // quick read
const int inf = 0x3f3f3f3f;
#define rf(i, n) for (int i = 1; i <= (n); ++i)
using ll = __int128_t;
const int max_size = 5 + 100;
const int maxn = 5 + 100;

int n, m;
int a[max_size];
ll f[max_size][max_size];  // f[i][j] 表示剩下区间 [i, j] 的最大取数价值

/*
问题转化：
做 n 次区间 dp
    各行各取各的
    从两端取数，剩下的数是一个区间

f[i][j] = max(f[i - 1][j] + a[i - 1] * (m - (j - i + 1)), f[i][j + 1] + a[j + 1] * (m - (j - i + 1)))

*/

ll dp() {
    memset(f, 0, sizeof(f));
    ll base = 2;
    for (int siz = m - 1; siz > 0; --siz) {
        for (int l = 1, r = l + siz - 1; r <= m; ++l, ++r) {
            f[l][r] = max(f[l - 1][r] + a[l - 1] * base, f[l][r + 1] + a[r + 1] * base);
        }
        base <<= 1;
    }
    ll ans = 0;
    rf(i, m) ans = max(ans, f[i][i] + a[i] * base);
    return ans;
}

void show(ll x) {
    if (x == 0) return;
    show(x / 10);
    putchar(x % 10 + '0');
}

int main() {
    n = rad(), m = rad();
    ll ans = 0;
    rf(i, n) {
        rf(j, m) a[j] = rad();
        ans += dp();
    }
    if (ans)
        show(ans);
    else
        putchar('0');
}

T rad() {
    T back = 0;
    int ch = 0, posi = 0;
    for (; ch < '0' || ch > '9'; ch = getchar())
        posi = ch ^ '-';
    for (; ch >= '0' && ch <= '9'; ch = getchar())
        back = (back << 1) + (back << 3) + (ch & 0xf);
    return posi ? back : -back;
}